#include "Timer8BitAsync.h"

unsigned long int Timer8BitAsync::getFrequency(
			unsigned long int CLK_IO,
			unsigned long int N,
			unsigned long int OCR_n
				)
{

	double value = CLK_IO / (2.0 * N * (1 + OCR_n));
	unsigned long int f = (unsigned long int) value;
	return f;
}



unsigned long int Timer8BitAsync::getFrequencyFastPWM(
			unsigned long int CLK_IO,
			unsigned long int N
				)
{

	double value = CLK_IO / (2.0 * N * (256));
	unsigned long int f = (unsigned long int) value;
	return f;
}

unsigned long int Timer8BitAsync::getFrequencyPhaseCorrectPWM(
			unsigned long int CLK_IO,
			unsigned long int N
				)
{

	double value = CLK_IO / (2.0 * N * (510));
	unsigned long int f = (unsigned long int) value;
	return f;
}

void Timer8BitAsync::setUp(
			unsigned char forceOutputCompare,
			unsigned char prescaler,
			unsigned char counter,
			unsigned char setAsync,
			unsigned char outputCompare,
			unsigned char setprescaleReset
			)
{
	setClockSelectAsyncTimer8Bit(prescaler);
	setCounterAsyncTimer8Bit(counter);
	setOutputCompareAsyncTimer8Bit(outputCompare);
	setAsyncAsyncTimer8Bit(setAsync);
	setPrescalerResetAsyncTimer8Bit(setprescaleReset);
	setForceOutputCompareAsyncTimer8Bit(forceOutputCompare);
}


void Timer8BitAsync::setForceOutputCompare(unsigned char flag)
{
	TCCR2 = SetBit(TCCR2, FOC2, flag);
}


void Timer8BitAsync::setWaveformGenerationMode(unsigned char flag)
{
	switch(flag)
	{
		case NormalWaveformGenerationAsyncTimer8Bit:
			TCCR2 = SetBit(TCCR2, WGM21, 0);
			TCCR2 = SetBit(TCCR2, WGM20, 0);
			break;
		case PWM_PhaseCorrectAsyncTimer8Bit:
			TCCR2 = SetBit(TCCR2, WGM21, 0);
			TCCR2 = SetBit(TCCR2, WGM20, 1);
			break;
		case CTC_AsyncTimer8Bit:
			TCCR2 = SetBit(TCCR2, WGM21, 1);
			TCCR2 = SetBit(TCCR2, WGM20, 0);
			break;
		case FastPWM_AsyncTimer8Bit:
			TCCR2 = SetBit(TCCR2, WGM21, 1);
			TCCR2 = SetBit(TCCR2, WGM20, 1);
			break;
		default:
			TCCR2 = SetBit(TCCR2, WGM21, 0);
			TCCR2 = SetBit(TCCR2, WGM20, 0);
			break;
	}
}


void Timer8BitAsync::setCompareMatchOutputMode(unsigned char flag)
{
	switch(flag)
	{
		case NormalPortOperation_OC2_Disconnected:
			TCCR2 = SetBit(TCCR2, WGM21, 0);
			TCCR2 = SetBit(TCCR2, WGM20, 0);
			break;
		case ToggleOC2onCompareMatch:
			TCCR2 = SetBit(TCCR2, WGM21, 0);
			TCCR2 = SetBit(TCCR2, WGM20, 1);
			break;
		case ClearOC2onCompareMatch:
			TCCR2 = SetBit(TCCR2, WGM21, 1);
			TCCR2 = SetBit(TCCR2, WGM20, 0);
			break;
		case SetOC2onCompareMatch:
			TCCR2 = SetBit(TCCR2, WGM21, 1);
			TCCR2 = SetBit(TCCR2, WGM20, 1);
			break;
		default:
			TCCR2 = SetBit(TCCR2, WGM21, 0);
			TCCR2 = SetBit(TCCR2, WGM20, 0);
			break;
	}
}



void Timer8BitAsync::setClockSelect(unsigned char flag)
{
	switch(flag)
	{
		case NoClockSourceAsynTimer8Bit:
			TCCR2 = SetBit(TCCR2, CS22, 0);
			TCCR2 = SetBit(TCCR2, CS21, 0);
			TCCR2 = SetBit(TCCR2, CS20, 0);
			break;
		case NoPrescaler_AsynTimer8Bit:
			TCCR2 = SetBit(TCCR2, CS22, 0);
			TCCR2 = SetBit(TCCR2, CS21, 0);
			TCCR2 = SetBit(TCCR2, CS20, 1);
			break;
		case Prescaler8_AsynTimer8Bit:
			TCCR2 = SetBit(TCCR2, CS22, 0);
			TCCR2 = SetBit(TCCR2, CS21, 1);
			TCCR2 = SetBit(TCCR2, CS20, 0);
			break;
		case Prescaler64_AsynTimer8Bit:
			TCCR2 = SetBit(TCCR2, CS22, 0);
			TCCR2 = SetBit(TCCR2, CS21, 1);
			TCCR2 = SetBit(TCCR2, CS20, 1);
			break;
		case Prescaler256_AsynTimer8Bit:
			TCCR2 = SetBit(TCCR2, CS22, 1);
			TCCR2 = SetBit(TCCR2, CS21, 0);
			TCCR2 = SetBit(TCCR2, CS20, 0);
			break;
		case Prescaler1024_AsynTimer8Bit:
			TCCR2 = SetBit(TCCR2, CS22, 1);
			TCCR2 = SetBit(TCCR2, CS21, 0);
			TCCR2 = SetBit(TCCR2, CS20, 1);
			break;
		case ExternalClockFallingAsynTimer8Bit:
			TCCR2 = SetBit(TCCR2, CS22, 1);
			TCCR2 = SetBit(TCCR2, CS21, 1);
			TCCR2 = SetBit(TCCR2, CS20, 0);
			break;
		case ExternalClockRisingAsynTimer8Bit:
			TCCR2 = SetBit(TCCR2, CS22, 1);
			TCCR2 = SetBit(TCCR2, CS21, 1);
			TCCR2 = SetBit(TCCR2, CS20, 1);
			break;
		default:
			TCCR2 = SetBit(TCCR2, CS22, 0);
			TCCR2 = SetBit(TCCR2, CS21, 0);
			TCCR2 = SetBit(TCCR2, CS20, 0);
			break;
	}
}


void Timer8BitAsync::setCounter(unsigned char flag)
{
	TCNT2 = flag;
}

unsigned char Timer8BitAsync::getCounter()
{
	return TCNT2;
}

void Timer8BitAsync::setOutputCompare(unsigned char flag)
{
	OCR2 = flag;
}

unsigned char Timer8BitAsync::getOutputCompare()
{
	return OCR2;
}

void Timer8BitAsync::setAsync(unsigned char flag)
{
	ASSR = SetBit(ASSR, AS2, flag);
}

unsigned char Timer8BitAsync::getUpdateBusy()
{
	return GetBit(ASSR, TCN2UB);
}

unsigned char Timer8BitAsync::getUpdateBusyOutputCompare()
{
	return GetBit(ASSR, OCR2UB);
}

unsigned char Timer8BitAsync::getUpdateBusyCounterControl()
{
	return GetBit(ASSR, TCR2UB);
}

void Timer8BitAsync::setOutputCompareInterruptEnable(unsigned char flag)
{
	TIMSK = SetBit(TIMSK, OCIE2, flag);
}

void Timer8BitAsync::setOverflowInterruptEnable(unsigned char flag)
{
	TIMSK = SetBit(TIMSK, TOIE2, flag);
}

unsigned char Timer8BitAsync::getOutputCompareFlag()
{	
	return GetBit(TIFR, OCF2);
}
unsigned char Timer8BitAsync::getOverflowFlag()
{
	return GetBit(TIFR, TOV2);
}

void Timer8BitAsync::setPrescalerReset(unsigned char flag)
{
	SFIOR = SetBit(SFIOR, PSR2, flag);
}


